﻿#ifndef XQTABLEPAGINGWIDGET_H
#define XQTABLEPAGINGWIDGET_H
#define TABLEDATA (Qt::UserRole+1) //用在表格映射存储的数据
#include<QReadWriteLock>
#include<QWidget>
#include<QVariant>
#include<QBoxLayout>
#include"XQHead.h"
#include"XQTablePagingItem.h"
//分页表格小部件
class XQTablePagingWidget:public QWidget
{
	Q_OBJECT
public:
	XQTablePagingWidget(QWidget* parent = nullptr,bool AutoInit=true);
	~XQTablePagingWidget();
	//返回全部数据
	QList<XQTablePagingItem>& datas();
	const QList<XQTablePagingItem>& datas()const;
	//返回显示的数据
	const QList<XQTablePagingItem>& showDatas()const;
	//返回查询按钮
	XQComboCheckButton* findButton()const;
	//返回过滤按钮
	XQComboCheckButton* filterButton()const;
	//返回QTableWidget*
	QTableWidget* tableWidget()const;
	//获取水平标题
	QStringList horizontalTitle()const;
	//正在排序中吗
	bool isSortBeing()const;
	//获取列数
	int columnCount()const;
	//获取数据个数
	size_t dataSize();
	//布局排列方向
	QBoxLayout::Direction direction()const;
	//返回锁
	QReadWriteLock* dataLock();
public:
	//过滤数据
	void filter(std::function<bool(const XQTablePagingItem&)> func);
	//设置排序函数方法
	template <typename T>
	void setSortFunc(int nSel, std::function<bool(const T& front, const T& later)>compare);
	//设置排序函数方法
	void setSortFunc(int nSel, std::function<bool(const QPair<QString, QVariant>& front, const QPair<QString, QVariant>& later)>sort);
	//添加过滤器
	void addFilter(const QString& name, std::function<bool(const XQTablePagingItem& item)> func,bool on=false);
	//清空过滤器
	void clearFilter();
public slots:
	//设置水平标题
	void setHorizontalTitle(const QStringList& title);
	//添加数据
	void push_backRow(const QStringList& text);
	void push_backRow(const XQTablePagingItem& data);
	void push_backRow(XQTablePagingItem&& data);
	void push_frontRow(const QStringList& text);
	void push_frontRow(const XQTablePagingItem& data);
	void push_frontRow(XQTablePagingItem&& data);
	void pop_frontRow();
	void pop_backRow();
	//清空数据
	void clearData();
	//清空表格
	void clearTable();
	//设置数量
	void setCount(size_t count);
	//设置页数
	void setPages(size_t count);
	//设置表格刷新时间
	void setTableUpdataTime(int sec);
	//逆序数据
	void reverse(QList<XQTablePagingItem>* data);
	void reverse();
	//排序
	virtual void sort(int nSel);
	//设置布局排列
	void setDirection(QBoxLayout::Direction direction);
	//设置功能栏可见性
	void setPaletteVisible(bool Visible);
public://右键菜单
	//设置右键菜单函数
	void setContextMenuFunc(std::function<void()> contextMenuFunc);
	//设置默认的右键菜单函数
	void setContextMenuFunc();
	//添加默认菜单
	void menuAddDefaultMenu(QMenu* menu);
	//菜单添加隐藏显示其中某一列
	void menuAddColumnHidden(QMenu* menu);
	//菜单添加隐藏显示功能栏
	void menuAddShowPalette(QMenu* menu);
	//菜单添加设置排列方向
	void menuAddDirection(QMenu* menu);
	//菜单添加导出功能
	void menuAddExport(QMenu* menu);
	//菜单添加复制到剪切板功能
	void menuAddCopy(QMenu* menu);
public:
	//显示全部数据
	void showDataAll();
	//显示过滤后的数据
	void showFilterData();
	//显示搜索的数据
	void showSearchData();
	//显示表格
	void showTable(int n=0);
	//更新表格
	void updataTable();
	//查询搜索
	void findSearch();
	//过滤数据,过滤按钮触发
	void filter();
signals://信号
	//排序开始
	void sortStart();
	//排序结束
	void sortFinish();
	//数据数量改变
	void dataCountChange(qint64 count);
protected://隐藏的函数
	//计算当前可以有多少行
	int rowNumber();
	//初始化微调框ui
	void init_PagingUI(size_t count);
protected://初始化ui
	virtual void init();
	virtual void init_ui();
	virtual QWidget* init_paging();
	virtual void tableWidget_init();
	virtual void updataTimer_init();
protected://事件
	void resizeEvent(QResizeEvent* event)override;
	void closeEvent(QCloseEvent* event)override;
	void showEvent(QShowEvent*)override;
	//表格弹出菜单
	virtual void contextMenuRequested();
protected://变量
	QWidget* m_paletteWidget = nullptr;//功能区小部件
	std::function<void()> m_contextMenuFunc=nullptr;//弹出的右键菜单函数
	XQTableExportWidget* m_exportWidget = nullptr;//导出的小部件
	XQComboCheckButton* m_filterBtn = nullptr;//过滤
	QComboBox* m_findEdit = nullptr;//搜索组合框
	XQComboCheckButton* m_findBtn = nullptr;//查询按钮
	QPushButton* m_reverseBtn = nullptr;//逆序按钮
	QComboBox* m_updataBox = nullptr;//刷新时间
	QTimer* m_updataTimer = nullptr;//刷新定时器
	QLabel* m_count = nullptr;//数量
	QLabel* m_Pages = nullptr;//页数
	int m_onePageCount = 0;//一页数量
	int m_nSel = 0;//当前页记录
	QTableWidget* m_tableWidget = nullptr;
	QSpinBox* m_paging = nullptr;//分页微调框
	QList<XQTablePagingItem>* m_showData = &m_data;//显示的数据
	QReadWriteLock m_lock;//锁数据
	QList<XQTablePagingItem> m_data;//数据
	QList<XQTablePagingItem> m_filterData;//过滤后的数据
	QList<XQTablePagingItem> m_SearchData;//搜索的数据
	QList<bool>m_sortFlag;//排序记录是正序还是逆序
	QList<std::function<bool(const QPair<QString,QVariant>&, const QPair<QString, QVariant>&)>>m_sortFunc;//排序方法函数
	bool m_sortBeing = false;//正在排序中

	QMap<QString, int> m_filterMap_nSel;//索引映射
	QMap<int, std::function<bool(const XQTablePagingItem&)>> m_filterMap_func;//函数映射
};
template <typename T>
void XQTablePagingWidget::setSortFunc(int nSel, std::function<bool(const T& front, const T& later)>compare)
{
	setSortFunc(nSel, [=](const QPair<QString, QVariant>& front, const QPair<QString, QVariant>& later)
		{
			return compare(front.second.value<T>(), later.second.value<T>());
		});
}
#endif // !XQTablePagingWidget_H
